
# ifndef __DFX_GRAPHICS_DEVICE_H__
# define __DFX_GRAPHICS_DEVICE_H__

# include "dfxCore.h"
# include "dfxColor4.h"
# include "dfxSingleton.h"
# include "dfxWindow.h"
# include "dfxCorePlugin.h"

# include "dfxProgram.h"
# include "dfxRenderData.h"
# include "dfxRenderState.h"
# include "dfxMaterial.h"
# include "dfxVertexManager.h"

namespace DFX
{
    enum CLEAR_FLAGS
    {
        CLEAR_FLAGS_TARGET  = 1 << 0,
        CLEAR_FLAGS_DEPTH   = 1 << 1,
        CLEAR_FLAGS_STENCIL = 1 << 2
    };

    class DFX_EXPORT GraphicsDevice : public Singleton<GraphicsDevice>
    {
    public:

        GraphicsDevice()
        {
        }

        virtual ~GraphicsDevice()
        {
        }

        virtual Window* GetWindow() = 0;

        virtual DFXRESULT Initialize(Window *window) = 0;
        virtual DFXRESULT Destroy() = 0;

        virtual DFXRESULT CreateAdditional(Window *window) = 0;

        virtual Texture* CreateTexture(const String &name, TEXTURE_TYPE type, UInt32 usage, bool mipMaps) = 0;
        virtual Program* CreateProgram(const String &name) = 0;
        virtual RenderData* CreateRenderData(const String &name) = 0;

        virtual AlphaState* CreateAlphaState(const AlphaStateDescription &desc) = 0;
        virtual RasterizerState* CreateRasterizeState(const RasterizerStateDescription &desc) = 0;
        virtual DepthState* CreateDepthState(const DepthStateDescription &desc) = 0;
        virtual StencilState* CreateStencilState(const StencilStateDescription &desc) = 0;

        virtual void SetAlphaState(AlphaState *state) = 0;
        virtual void SetRasterizerState(RasterizerState *state) = 0;
        virtual void SetDepthState(DepthState *state) = 0;
        virtual void SetStencilState(StencilState *state) = 0;
        virtual void SetMaterial(Material *material) = 0;
        virtual void SetRenderData(RenderData *data) = 0;

        virtual void Clear(UInt32 flags, const Color4 &c, Float32 depth = 1.0f, Int32 stencil = 0) = 0;
        virtual void Present(Window *window) = 0;

        virtual void SetCurrent(Window *window) = 0;
    };
}

# endif